package com.itserver.aop;

import com.itserver.mapper.OperateLogMapper;
import com.itserver.pojo.OperateLog;
import com.itserver.utils.CurrentHolder;

import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.time.LocalDateTime;
import java.util.Arrays;

@Slf4j
@Aspect
@Component

public class LogAspect {

    @Autowired
    private  OperateLogMapper operateLogMapper;

    @Pointcut("@annotation(com.itserver.ano.Log)")
    public void logPointcut() {}

    // 环绕通知
    @Around("execution(* com.itserver.service.sys.impl.*.*(..)) && !execution(* com.itserver.service.sys.impl.LogServiceImpl.*(..))")
    //添加事务

    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable{
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        String methodType = "" ;
        String path ="";
        String ip = "";
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            // 获取请求方法
            methodType = request.getMethod();
            // 获取请求路径
            path = request.getRequestURI();
            // 获取请求IP
            ip = request.getHeader("X-Real-IP");
            if (ip == null || ip.isEmpty()) {
                ip = request.getHeader("X-Forwarded-For");
            }
        }
        long startTime = System.currentTimeMillis(); // 开始时间
        Object result = joinPoint.proceed(); // 执行目标方法
        log.info("目标方法执行了：{}",joinPoint.getSignature().getName());

        long endTime = System.currentTimeMillis(); // 结束时间
        long costTime = endTime - startTime; // 计算耗时

        // 构建日志对象
        OperateLog operateLog = new OperateLog();

        operateLog.setOperateUserName(getCurrentUserName()); // 获取当前操作人ID
        operateLog.setOperateTime(LocalDateTime.now()); // 当前时间
        operateLog.setClassName(joinPoint.getTarget().getClass().getName()); // 目标类的全类名
        operateLog.setMethodName(joinPoint.getSignature().getName()); // 目标方法名
        operateLog.setMethodParams(Arrays.toString(joinPoint.getArgs())); // 方法运行时参数
        operateLog.setMethodType(methodType); // 请求方式
        operateLog.setPath(path); // 请求路径

        operateLog.setIp(ip); // 请求IP
        log.info("用户ip:{}", ip);
        if(result != null){
            operateLog.setReturnValue(result.toString()); // 方法返回值
        }
        operateLog.setCostTime(costTime); // 方法执行时长

        // 保存日志
        operateLogMapper.insert(operateLog);

        return result;
    }

    // 获取当前操作人ID的方法（需要根据实际情况实现）
    private String getCurrentUserName() {
        // 假设从某个上下文中获取当前登录用户名
        // 这里只是一个示例，实际项目中需要根据自己的安全框架或上下文管理来实现
        return (String) CurrentHolder.getCurrent(); // 示例返回值
    }
}